/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package web.diva.server.model;

import java.awt.Color;
import java.util.HashMap;
import java.util.HashSet;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.axis.SymbolAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.SeriesRenderingOrder;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 *
 * @author Yehia Farag
 */
public class LineChartGenerator {

    private final JFreeImgGenerator imgGenerator;
    private HashSet<Integer> indexMarker = new HashSet<Integer>();

    public LineChartGenerator(Number[][] pointsData, String[] rowIds, String[] columnIds, String[] colors, HashMap<String, Color> colorMap) {

        imgGenerator = new JFreeImgGenerator();
        XYDataset dataset = createDataset(pointsData);
        chart = createChart(dataset, columnIds, colors, colorMap);
        System.gc();
    }

    /**
     *
     * @return dataset.
     */
    private XYDataset createDataset(Number[][] pointsData) {

        final XYSeriesCollection dataset = new XYSeriesCollection();
        for (int x = 0; x < pointsData.length; x++) {
            XYSeries series = new XYSeries(x);
            Number[] data = pointsData[x];
            for (int y = 0; y < data.length; y++) {
                series.add(y, data[y]);
            }
            dataset.addSeries(series);

        }
        return dataset;

    }
    private final JFreeChart chart;

    /**
     * Creates a chart.
     *
     * @param dataset the data for the chart.
     * @param lcr the line chart result
     *
     * @return a chart.
     */
    private JFreeChart createChart(final XYDataset dataset, String[] columnIds, String[] colors, HashMap<String, Color> colorMap) {

        JFreeChart temChart = ChartFactory.createXYLineChart(
                "", // chart title
                "", // x axis label
                "", // y axis label
                dataset, // data
                PlotOrientation.VERTICAL,
                false, // include legend
                false, // tooltips
                false // urls
        );

        temChart.setBackgroundPaint(Color.WHITE);

        final XYPlot plot = temChart.getXYPlot();
        plot.setBackgroundPaint(Color.WHITE);
        plot.setDomainGridlinePaint(Color.WHITE);
        plot.setRangeGridlinePaint(Color.WHITE);

        XYLineAndShapeRenderer renderer = this.chartColorUpdate(null, colors, colorMap);
        for (int x = 0; x < colors.length; x++) {
            renderer.setSeriesLinesVisible(x, false);
        }
        plot.setRenderer(renderer);
        plot.setSeriesRenderingOrder(SeriesRenderingOrder.REVERSE);

        SymbolAxis rangeAxis = new SymbolAxis("", columnIds);
        rangeAxis.setGridBandsVisible(false);
        rangeAxis.setVerticalTickLabels(true);
        rangeAxis.setVisible(true);
        rangeAxis.setFixedDimension(51.0);

        boolean auto = rangeAxis.getAutoRangeIncludesZero();
        rangeAxis.setAutoRangeIncludesZero(true ^ auto);
        rangeAxis.setTickUnit(new NumberTickUnit(1));
        rangeAxis.setRange(0, columnIds.length);
        plot.setDomainAxis(rangeAxis);
        return temChart;

    }

    public void updateChartColors(String[] colors, HashMap<String, Color> colorMap) {
        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer();
        this.chartColorUpdate(renderer, colors, colorMap);

    }

    private XYLineAndShapeRenderer chartColorUpdate(XYLineAndShapeRenderer renderer, String[] colors, HashMap<String, Color> colorMap) {
        if (renderer == null) {
            renderer = new XYLineAndShapeRenderer();
        }
        renderer.setShapesVisible(false);
        if (colorMap.size() > 2) {
            for (int x = 0; x < colors.length; x++) {
                if (colors[x].equalsIgnoreCase("#000000")) {
                    renderer.setSeriesPaint(x, Color.BLACK);
                    continue;
                }
                renderer.setSeriesPaint(x, colorMap.get(colors[x]));
            }
        } else {
            renderer.setPaint(Color.BLACK);
        }
        return renderer;

    }

    public String selectionUpdateChart(int[] selection, String path, String imgName, double width, double height) {
        String chartUrl = "";

        if (selection != null) {

            XYPlot plot = chart.getXYPlot();
            XYLineAndShapeRenderer updatedRenderer = (XYLineAndShapeRenderer) plot.getRenderer();
            for (int x : indexMarker) {
                updatedRenderer.setSeriesLinesVisible(x, false);
            }
            indexMarker.clear();
            for (int x = 0; x < selection.length; x++) {
                updatedRenderer.setSeriesLinesVisible(selection[x], true);
                indexMarker.add(selection[x]);
            }
        }
        chartUrl = generateChart(chart, path, imgName, width, height);
        return chartUrl;
    }

    private String generateChart(JFreeChart chart, String path, String imgName, double width, double height) {
        String imgurl = imgGenerator.saveToFile(chart, width, height, path, null, imgName);
        return imgurl;
    }

}
